<script lang="ts" setup>
import { reactive, ref, onMounted, computed } from "vue"
import * as audio from "@/api/audio"
import { ElMessage, ElLoading } from "element-plus"
import type { FileRecordRequestData, FileRecord } from "@/api/audio/types/audio"
import { isMobile } from "@/utils/validate"

const mobile = computed(isMobile)
console.log("isMobile", mobile.value)

const searchData = reactive({ title: "", desc: "" })

const tableData = reactive<FileRecord[]>([])
const total = ref(0)
const pageSize = ref(50)
const currentPage = ref(1)
const listAudio = () => {
  const data: FileRecordRequestData = {
    offset: (currentPage.value - 1) * pageSize.value,
    step: pageSize.value,
    title: searchData.title,
    desc: searchData.desc
  }
  audio
    .audios(data)
    .then((res) => {
      tableData.length = 0
      total.value = res.total
      if (res?.data instanceof Array) {
        tableData.push(...res.data)
      }
    })
    .catch((res) => {
      ElMessage.error(`查询音频文件列表失败！${res?.msg || ""}`)
    })
}

const clearSearchData = () => {
  searchData.desc = ""
  searchData.title = ""
  currentPage.value = 1
  listAudio()
}

const pageSizeChange = () => {
  currentPage.value = 1
  listAudio()
}

onMounted(listAudio)

const currentAudio = reactive({ title: "", desc: "", id: 0 })
let source: AudioBufferSourceNode | undefined = undefined
const context = new AudioContext()

const startAudio = (row: FileRecord) => {
  if (!row) {
    return
  }
  stopAudio()
  // const context = new AudioContext()
  const loadingInstance = ElLoading.service({ text: "正在缓冲..." })
  audio
    .play(String(row.id))
    .then((res) => res.data)
    .then((arrayBuffer) => context.decodeAudioData(arrayBuffer))
    .then((audioBuffer) => {
      loadingInstance.close()
      source = context.createBufferSource()
      source.buffer = audioBuffer
      source.connect(context.destination)
      source.start()
      audioState.value = "running"
      currentAudio.title = row.title
      currentAudio.desc = row.desc
      currentAudio.id = row.id
      listAudio()
    })
    .catch(() => {
      loadingInstance.close()
      ElMessage.error(`播放音频文件失败！`)
      stopAudio()
    })
}
const stopAudio = () => {
  console.log("stopAudio", currentAudio)
  source?.stop()
  source = undefined
  currentAudio.title = ""
  currentAudio.desc = ""
  currentAudio.id = 0
}

const audioState = ref("")
const toggleAudio = () => {
  console.log("toggle", currentAudio)
  if (context.state === "running") {
    context.suspend()
    audioState.value = "suspended"
  } else if (context.state === "suspended") {
    context.resume()
    audioState.value = "running"
  }
}
</script>

<template>
  <!-- 桌面页面 -->
  <div v-if="!mobile" class="app-container">
    <el-card shadow="never" class="search-wrapper">
      <div class="flex flex-row overflow-hidden">
        <el-form class="flex flex-row gap-x-4 mr-4" ref="searchFormRef" :model="searchData" label-position="top">
          <el-form-item class="w-64" prop="title" label="文件名">
            <el-input v-model="searchData.title" placeholder="请输入" />
          </el-form-item>
          <el-form-item class="w-64" prop="desc" label="文件描述">
            <el-input v-model="searchData.desc" placeholder="请输入" />
          </el-form-item>
        </el-form>
        <el-button class="self-end mb-[18px]" type="primary" @click="listAudio">确定</el-button>
        <el-button class="self-end mb-[18px]" @click="clearSearchData">重置</el-button>
        <div
          v-if="currentAudio.title"
          class="self-end mb-[18px] ml-[24px] h-[64px] px-2 gap-x-2 flex flex-row-reverse flex-grow overflow-hidden border-dashed border border-gray rounded"
        >
          <el-icon :size="36" class="self-center cursor-pointer" @click="toggleAudio"
            ><VideoPlay v-if="audioState == 'suspended'" class="text-blue-400" /><VideoPause
              v-if="audioState == 'running'"
              class="text-blue-400"
            />
          </el-icon>
          <div class="self-center flex-grow overflow-hidden">
            <!-- <div class="text-gray text-sm"></div> -->
            <el-tooltip effect="dark" :content="currentAudio.title" placement="bottom">
              <div class="overflow-hidden truncate text-sm text-black">{{ currentAudio.title }}</div>
            </el-tooltip>
            <el-tooltip effect="dark" :content="currentAudio.desc" placement="bottom">
              <div class="truncate text-gray text-sm">{{ currentAudio.desc }}</div>
            </el-tooltip>
          </div>
        </div>
      </div>
    </el-card>
    <el-card shadow="never">
      <el-table :data="tableData">
        <el-table-column prop="title" label="文件名" show-overflow-tooltip width="256" />
        <el-table-column prop="desc" label="文件描述" show-overflow-tooltip />
        <el-table-column prop="playcount" label="播放次数" width="100" />
        <el-table-column prop="createtime" label="上传时间" width="160" />
        <el-table-column label="操作" width="60">
          <template #default="scope">
            <el-button type="primary" text size="small" @click="startAudio(scope.row)">播放</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div class="flex flex-row-reverse mt-[8px]">
        <el-pagination
          v-if="total > 0"
          layout="prev,pager,next,sizes"
          :total="total"
          v-model:page-size="pageSize"
          :page-sizes="[3, 10, 30, 50, 100]"
          @size-change="pageSizeChange"
          v-model:current-page="currentPage"
          @current-change="listAudio"
        />
      </div>
    </el-card>
  </div>

  <!-- 移动端页面 -->
  <div v-if="mobile" class="bg-white w-full">
    <div class="flex flex-col px-4">
      <el-form ref="searchFormRef" :model="searchData">
        <el-form-item prop="title" label="名称：">
          <el-input v-model="searchData.title" placeholder="请输入文件名" clearable @change="listAudio" />
        </el-form-item>
        <el-form-item prop="desc" label="描述：">
          <el-input v-model="searchData.desc" placeholder="请输入文件描述" clearable @change="listAudio" />
        </el-form-item>
      </el-form>
    </div>
    <div class="px-4 flex flex-col gap-y-2 mb-4">
      <div class="flex flex-row w-full justify-between">
        <div class="text-gray">{{ "正在播放：" }}</div>
        <el-button size="small" type="primary" round @click="toggleAudio" v-if="audioState == 'running'"
          >暂停</el-button
        >
        <el-button size="small" type="primary" round @click="toggleAudio" v-if="audioState == 'suspended'"
          >播放</el-button
        >
      </div>
      <div class="truncate text-black">{{ currentAudio.title }}</div>
    </div>
    <el-table :data="tableData" highlight-current-row @current-change="startAudio">
      <el-table-column label="文件列表">
        <template #default="scope">
          <div class="flex flex-col">
            <div class="flex flex-row justify-between">
              <div>{{ scope.row.title }}</div>
              <div class="text-gray">{{ `播放${scope.row.playcount}次` }}</div>
            </div>
            <div class="truncate text-gray">{{ scope.row.desc }}</div>
            <div class="self-end text-gray">{{ `上传时间：${scope.row.createtime}` }}</div>
          </div>
        </template>
      </el-table-column>
    </el-table>
    <div class="flex flex-row-reverse mt-[8px]">
      <el-pagination
        v-if="total > 0"
        layout="prev,pager,next,sizes"
        :total="total"
        v-model:page-size="pageSize"
        :page-sizes="[3, 10, 30, 50, 100]"
        @size-change="pageSizeChange"
        v-model:current-page="currentPage"
        @current-change="listAudio"
      />
    </div>
  </div>
</template>

<style lang="scss" scoped>
.search-wrapper {
  margin-bottom: 20px;
  :deep(.el-card__body) {
    padding-bottom: 2px;
  }
}
</style>
